package main

import (
	"net"
	"strings"
)

//定义用户结构体
type User struct {
	Name    string
	Address string
	Channel chan string
	Conn    net.Conn
	Server *Server
}

const (
	Separator       = " "
	QueryOnlineUser = "query"
	RenameUser      = "rename" + Separator
	SendToUser      = "to" + Separator
)

//创建User
func NewUser(conn net.Conn, server *Server) *User {
	addr := conn.RemoteAddr().String()
	user := &User{
		Name:    addr,
		Address: addr,
		Channel: make(chan string),
		Conn:    conn,
		Server:  server,
	}
	go user.ListenMessage()
	return user
}

//监听User的Channel
func (user *User) ListenMessage() {
	for {
		msg := <-user.Channel
		user.Conn.Write([]byte(msg + "\n"))
	}
}

//用户上线
func (user *User) Online() {
	//用户加入到在线用户表
	user.Server.AddOnlineMap(user)
	//广播用户上线
	user.Server.BroadcastOnline(user, "上线了")
}

//用户下线
func (user *User) Offline() {
	//用户加入到在线用户表
	user.Server.DeleteOnlineMap(user)
	//广播用户上线
	user.Server.BroadcastOnline(user, "下线了")
}

//处理消息
func (user *User) ReceiveMessage(msg string) {
	switch {
	case msg == "":
		user.SendMessage("无消息内容请重发")
	case msg == QueryOnlineUser:
		user.Server.GetOnlineUsers(user)
	case len(msg) > len(RenameUser) && msg[0:len(RenameUser)] == RenameUser:
		user.RenameUser(msg)
	case len(msg) > len(SendToUser) && msg[0:len(SendToUser)] == SendToUser:
		user.SendToUser(msg)
	default:
		user.Server.BroadcastOnline(user, msg)
	}
}

//发送消息
func (user *User) SendMessage(msg string) {
	user.Conn.Write([]byte(msg + "\n"))
}

//更新用户名
func (user *User) RenameUser(msg string) {
	newName := msg[len(RenameUser):]
	_, ok := user.Server.OnlineMap[newName]
	if ok {
		user.SendMessage("当前用户名被占用")
		return
	}
	user.Server.DeleteOnlineMap(user)
	user.Name = newName
	user.Server.AddOnlineMap(user)

	user.SendMessage("更新用户名成功：" + user.Name)
}

//发送私聊
func (user *User) SendToUser(msg string) {
	contentArray := strings.Split(msg, Separator)
	//获取用户名id
	remoteName := contentArray[1]
	//根据用户名获取user
	if remoteName == "" {
		user.SendMessage("消息格式不正确，请使用格式\"to" + Separator + "张三" + Separator + "消息内容\"")
		return
	}
	remoteUser, ok := user.Server.GetUserByName(remoteName)
	if !ok {
		user.SendMessage("用户不存在或不在线")
		return
	}
	//获取消息内容，并发送
	content := contentArray[2]
	if content == "" {
		user.SendMessage("无消息内容请重发")
		return
	}
	remoteUser.SendMessage("[" + user.Address + "]" + user.Name + ":" + content)
}
